home *** CD-ROM | disk | FTP | other *** search
/ The World of Computer Software / The World of Computer Software.iso / vim_src.zip / AMIGA.C < prev    next >
C/C++ Source or Header  |  1993-01-12  |  26KB  |  1,206 lines

  1. /* vi:ts=4:sw=4
  2.  *
  3.  * VIM - Vi IMitation
  4.  *
  5.  * Code Contributions By:    Bram Moolenaar            mool@oce.nl
  6.  *                            Tim Thompson            twitch!tjt
  7.  *                            Tony Andrews            onecom!wldrdg!tony 
  8.  *                            G. R. (Fred) Walter        watmath!watcgl!grwalter 
  9.  */
  10.  
  11. /*
  12.  * amiga.c
  13.  *
  14.  * Amiga system-dependent routines.
  15.  */
  16.  
  17. #include "vim.h"
  18. #include "globals.h"
  19. #include "proto.h"
  20. #include "param.h"
  21.  
  22. #include <fcntl.h>
  23.  
  24. #undef TRUE             /* will be redefined by exec/types.h */
  25. #undef FALSE
  26.  
  27. #ifndef LATTICE
  28. #  include <exec/types.h>
  29. #  include <exec/exec.h>
  30. #  include <libraries/dos.h>
  31. #  include <libraries/dosextens.h>
  32. #  include <intuition/intuition.h>
  33. #else
  34. #  include <proto/dos.h>
  35. #  include <libraries/dosextens.h>
  36. #  include <proto/intuition.h>
  37. #  include <proto/exec.h>
  38. #endif
  39.  
  40. #include <libraries/arpbase.h>
  41. #if defined(LATTICE) && !defined(SASC)
  42. # include <libraries/arp_pragmas.h>
  43. #endif
  44.  
  45. /*
  46.  * At this point TRUE and FALSE are defined as 1L and 0L, but we want 1 and 0.
  47.  */
  48. #undef TRUE
  49. #define TRUE (1)
  50. #undef FALSE
  51. #define FALSE (0)
  52.  
  53. #ifndef AZTEC_C
  54. static long dos_packet __ARGS((struct MsgPort *, long, long));
  55. #endif
  56. static int lock2name __ARGS((BPTR lock, char *buf, long    len));
  57. static struct FileInfoBlock *get_fib __ARGS((char *));
  58.  
  59. static BPTR                raw_in = (BPTR)NULL;
  60. static BPTR                raw_out = (BPTR)NULL;
  61. static int                close_win = FALSE;    /* set if Vim opened the window */
  62.  
  63. struct IntuitionBase    *IntuitionBase = NULL;
  64. struct ArpBase            *ArpBase = NULL;
  65.  
  66. static struct Window    *wb_window;
  67. static char                *oldwindowtitle = NULL;
  68. static int                quickfix = FALSE;
  69.  
  70. int                        dos2 = FALSE;        /* Amiga DOS 2.0x or higher */
  71. int                        size_set = FALSE;    /* set to TRUE if window size was set */
  72.  
  73. static char                win_resize_on[]  = "\033[12{";
  74. static char                win_resize_off[] = "\033[12}";
  75.  
  76. /*
  77.  * the number of calls to Write is reduced by using the buffer "outbuf"
  78.  */
  79. #define BSIZE    2048
  80. static u_char            outbuf[BSIZE];
  81. static int                bpos = 0;        /* number of chars in outbuf */
  82.  
  83. /*
  84.  * flushbuf(): flush the output buffer
  85.  */
  86.     void
  87. flushbuf()
  88. {
  89.     if (bpos != 0)
  90.     {
  91.         Write(raw_out, (char *)outbuf, (long)bpos);
  92.         bpos = 0;
  93.     }
  94. }
  95.  
  96. /*
  97.  * outchar(c): put a character into the output buffer.
  98.  *               Flush it if it becomes full.
  99.  */
  100.     void
  101. outchar(c)
  102.     unsigned    c;
  103. {
  104.     outbuf[bpos] = c;
  105.     ++bpos;
  106.     if (bpos >= BSIZE)
  107.         flushbuf();
  108. }
  109.  
  110. /*
  111.  * GetChars(): low level input funcion.
  112.  * Get a characters from the keyboard.
  113.  * If type == T_PEEK do not wait for characters.
  114.  * If type == T_WAIT wait a short time for characters.
  115.  * If type == T_BLOCK wait for characters.
  116.  */
  117.     int
  118. GetChars(buf, maxlen, type)
  119.     char    *buf;
  120.     int        maxlen;
  121.     int        type;
  122. {
  123.     int        len;
  124.     long    time = 1000000L;    /* one second */
  125.  
  126.     switch (type)
  127.     {
  128.     case T_PEEK:
  129.         time = 100L;
  130.     case T_WAIT:
  131.         if (WaitForChar(raw_in, time) == 0)    /* no character available */
  132.             return 0;
  133.         break;
  134.  
  135.     case T_BLOCK:
  136.     /*
  137.      * If there is no character available within 2 seconds (default)
  138.      * write the autoscript file to disk
  139.      */
  140.         if (WaitForChar(raw_in, p_ut * 1000L) == 0)
  141.             updatescript(0);
  142.     }
  143.  
  144.     for (;;)        /* repeat until we got a character */
  145.     {
  146.         len = Read(raw_in, buf, (long)maxlen);
  147.         if (len > 0)
  148.             return len;
  149.     }
  150. }
  151.  
  152.     void
  153. sleep(n)
  154.     int             n;
  155. {
  156. #ifndef LATTICE            /* SAS declares void Delay(UNLONG) */
  157.     void            Delay __ARGS((long));
  158. #endif
  159.  
  160.     if (n > 0)
  161.         Delay((long)(50L * n));
  162. }
  163.  
  164.     void
  165. vim_delay()
  166. {
  167.     Delay(25L);
  168. }
  169.  
  170. /*
  171.  * We have no job control, fake it by starting a new shell.
  172.  */
  173. void
  174. mch_suspend()
  175. {
  176.     outstr("new shell started\n");
  177.     call_shell(NULL, 0);
  178. }
  179.  
  180. #define DOS_LIBRARY     ((UBYTE *) "dos.library")
  181.  
  182.     void
  183. mch_windinit()
  184. {
  185.     static char        intlibname[] = "intuition.library";
  186.     struct Library    *DosBase;
  187.  
  188. #ifdef AZTEC_C
  189.     Enable_Abort = 0;            /* disallow vim to be aborted */
  190. #endif
  191.     Columns = 80;
  192.     Rows = 24;
  193.  
  194. /*
  195.  * check if we are running under DOS 2.0x or higher
  196.  */
  197.     if (DosBase = OpenLibrary(DOS_LIBRARY, 37L))
  198.     {
  199.         CloseLibrary(DosBase);
  200.         dos2 = TRUE;
  201.     }
  202.  
  203.     /*
  204.      * Set input and output channels, unless we have opened our own window
  205.      */
  206.     if (raw_in == (BPTR)NULL)
  207.     {
  208.         raw_in = Input();
  209.         raw_out = Output();
  210.     }
  211.  
  212.     if (term_console)
  213.         outstr(win_resize_on);             /* window resize events activated */
  214.     flushbuf();
  215.  
  216.     wb_window = NULL;
  217.     if ((IntuitionBase = (struct IntuitionBase *)OpenLibrary((UBYTE *)intlibname, 0L)) == NULL)
  218.     {
  219.         fprintf(stderr, "cannot open %s!?\n", intlibname);
  220.         mch_windexit(3);
  221.     }
  222.     mch_get_winsize();
  223. }
  224.  
  225. #include <workbench/startup.h>
  226.  
  227. /*
  228.  * Check_win checks whether we have an interactive window.
  229.  * If not, a new window is opened with the newcli command.
  230.  * If we would open a window ourselves, the :sh and :! commands would not
  231.  * work properly (Why? probably because we are then running in a background CLI).
  232.  * This also is the best way to assure proper working in a next Workbench release.
  233.  *
  234.  * For the -e option (quickfix mode) we open our own window and disable :sh.
  235.  * Otherwise the compiler would never know when editing is finished.
  236.  */
  237. #define BUF2SIZE 320        /* lenght of buffer for argument with complete path */
  238.  
  239.     void
  240. check_win(argc, argv)
  241.     int argc;
  242.     char **argv;
  243. {
  244.     int                i;
  245.     BPTR            nilfh, fh;
  246.     char            buf1[20];
  247.     char            buf2[BUF2SIZE];
  248.     static char        *(constrings[3]) = {"con:0/0/662/210/",
  249.                                       "con:0/0/640/200/",
  250.                                       "con:0/0/320/200/"};
  251.     static char        winerr[] = "VIM: Can't open window!\n";
  252.     struct WBArg    *argp;
  253.     int                ac;
  254.     char            *av;
  255.     char            *device = NULL;
  256.     int                exitval = 4;
  257.  
  258.     if (!(ArpBase = (struct ArpBase *) OpenLibrary((UBYTE *)ArpName, ArpVersion)))
  259.     {
  260.         fprintf(stderr, "Need %s version %ld\n", ArpName, ArpVersion);
  261.         exit(3);
  262.     }
  263.  
  264. /*
  265.  * scan argv[] for the '-e' and '-d' arguments
  266.  */
  267.     for (i = 1; i < argc; ++i)
  268.         if (argv[i][0] == '-')
  269.         {
  270.             switch (argv[i][1])
  271.             {
  272.             case 'e':
  273.                 quickfix = TRUE;
  274.                 break;
  275.  
  276.             case 'd':
  277.                 if (i < argc - 1)
  278.                     device = argv[i + 1];
  279.                 break;
  280.             }
  281.         }
  282.  
  283. /*
  284.  * If we were not started from workbench, do not have a '-d' argument and
  285.  * we have been started with an interactive window, use that window.
  286.  */
  287.     if (argc != 0 && device == NULL &&
  288.                 IsInteractive(Input()) && IsInteractive(Output()))
  289.         return;
  290.  
  291. /*
  292.  * If we are in quickfix mode, we open our own window. We can't use the
  293.  * newcli trick below, because the compiler would not know when we are finished.
  294.  */
  295.     if (quickfix)
  296.     {
  297.         /*
  298.          * Try to open a window. First try the specified device.
  299.          * Then try a 24 line 80 column window.
  300.          * If that fails, try two smaller ones.
  301.          */
  302.         for (i = -1; i < 3; ++i)
  303.         {
  304.             if (i >= 0)
  305.                 device = constrings[i];
  306.             if (device && (raw_in = Open((UBYTE *)device, (long)MODE_NEWFILE)) != (BPTR)NULL)
  307.                 break;
  308.         }
  309.         if (raw_in == (BPTR)NULL)        /* all three failed */
  310.         {
  311.             fprintf(stderr, winerr);
  312.             goto exit;
  313.         }
  314.         raw_out = raw_in;
  315.         close_win = TRUE;
  316.         return;
  317.     }
  318.  
  319.     if ((nilfh = Open((UBYTE *)"NIL:", (long)MODE_NEWFILE)) == (BPTR)NULL)
  320.     {
  321.         fprintf(stderr, "Cannot open NIL:\n");
  322.         goto exit;
  323.     }
  324.  
  325.     /*
  326.      * make a unique name for the temp file (which we will not delete!)
  327.      */
  328.     sprintf(buf1, "t:nc%ld", buf1);    /* nobody else is using our stack */
  329.     if ((fh = Open((UBYTE *)buf1, (long)MODE_NEWFILE)) == (BPTR)NULL)
  330.     {
  331.         fprintf(stderr, "Cannot create %s\n", buf1);
  332.         goto exit;
  333.     }
  334.     /*
  335.      * Write the command into the file, put quotes around the arguments that
  336.      * have a space in them.
  337.      */
  338.     if (argc == 0)        /* run from workbench */
  339.         ac = ((struct WBStartup *)argv)->sm_NumArgs;
  340.     else
  341.         ac = argc;
  342.     for (i = 0; i < ac; ++i)
  343.     {
  344.         if (argc == 0)
  345.         {
  346.             *buf2 = NUL;
  347.             argp = &(((struct WBStartup *)argv)->sm_ArgList[i]);
  348.             if (argp->wa_Lock)
  349.                 lock2name(argp->wa_Lock, buf2, (long)(BUF2SIZE - 1));
  350.             TackOn(buf2, argp->wa_Name);
  351.             av = buf2;
  352.         }
  353.         else
  354.             av = argv[i];
  355.  
  356.         if (av[0] == '-' && av[1] == 'd')        /* skip '-d' option */
  357.         {
  358.             ++i;
  359.             continue;
  360.         }
  361.         if (strchr(av, ' '))
  362.             Write(fh, "\"", 1L);
  363.         Write(fh, av, (long)strlen(av));
  364.         if (strchr(av, ' '))
  365.             Write(fh, "\"", 1L);
  366.         Write(fh, " ", 1L);
  367.     }
  368.     Write(fh, "\nendcli\n", 8L);
  369.     Close(fh);
  370.  
  371. /*
  372.  * Try to open a new cli in a window. If '-d' argument was given try to open
  373.  * the specified device. Then try a 24 line 80 column window.
  374.  * If that fails, try two smaller ones.
  375.  */
  376.     for (i = -1; i < 3; ++i)
  377.     {
  378.         if (i >= 0)
  379.             device = constrings[i];
  380.         else if (device == NULL)
  381.             continue;
  382.         sprintf(buf2, "newcli <nil: >nil: %s from %s", device, buf1);
  383.         if (Execute((UBYTE *)buf2, nilfh, nilfh))
  384.             break;
  385.     }
  386.     if (i == 3)        /* all three failed */
  387.     {
  388.         DeleteFile((UBYTE *)buf1);
  389.         fprintf(stderr, winerr);
  390.         goto exit;
  391.     }
  392.     exitval = 0;    /* The Execute succeeded: exit this program */
  393.  
  394. exit:
  395.     CloseLibrary((struct Library *) ArpBase);
  396.     exit(exitval);
  397. }
  398.  
  399. /*
  400.  * fname_case(): Set the case of the filename, if it already exists.
  401.  *                 This will cause the filename to remain exactly the same.
  402.  */
  403.     void
  404. fname_case(name)
  405.     char *name;
  406. {
  407.     register struct FileInfoBlock    *fib;
  408.     register size_t                    len;
  409.  
  410.     fib = get_fib(name);
  411.     if (fib != NULL)
  412.     {
  413.         len = strlen(name);
  414.         if (len == strlen(fib->fib_FileName))    /* safety check */
  415.                 memmove(name, fib->fib_FileName, len);
  416.         free(fib);
  417.     }
  418. }
  419.  
  420. /*
  421.  * Get the FileInfoBlock for file "fname"
  422.  * The returned structure has to be free()d.
  423.  * Returns NULL on error.
  424.  */
  425.     static struct FileInfoBlock *
  426. get_fib(fname)
  427.     char *fname;
  428. {
  429.     register BPTR                    flock;
  430.     register struct FileInfoBlock    *fib;
  431.  
  432.     if (fname == NULL)        /* safety check */
  433.         return NULL;
  434.     fib = (struct FileInfoBlock *)malloc(sizeof(struct FileInfoBlock));
  435.     if (fib != NULL)
  436.     {
  437.         flock = Lock((UBYTE *)fname, (long)ACCESS_READ);
  438.         if (flock == (BPTR)NULL || !Examine(flock, fib))
  439.         {
  440.             free(fib);    /* in case of an error the memory is freed here */
  441.             fib = NULL;
  442.         }
  443.         if (flock)
  444.             UnLock(flock);
  445.     }
  446.     return fib;
  447. }
  448.  
  449. /*
  450.  * settitle(): set titlebar of our window
  451.  */
  452. static char *lasttitle = NULL;
  453.  
  454.     void
  455. settitle(str)
  456.     char *str;
  457. {
  458.  
  459.     if (wb_window != NULL)
  460.     {
  461.         free(lasttitle);
  462.         lasttitle = alloc((unsigned)(strlen(str) + 7));
  463.         if (lasttitle != NULL)
  464.         {
  465.             sprintf(lasttitle, "VIM - %s", str);
  466.             SetWindowTitles(wb_window, (UBYTE *)lasttitle, (UBYTE *)-1L);
  467.         }
  468.     }
  469. }
  470.  
  471.     void
  472. resettitle()
  473. {
  474.         if (wb_window != NULL && lasttitle != NULL)
  475.                 SetWindowTitles(wb_window, (UBYTE *)lasttitle, (UBYTE *)-1L);
  476. }
  477.  
  478. /*
  479.  * get name of current directory into buffer 'buf' of length 'len' bytes
  480.  */
  481. dirname(buf, len)
  482.     char        *buf;
  483.     int            len;
  484. {
  485.     return FullName("", buf, len);
  486. }
  487.  
  488. /*
  489.  * get absolute filename into buffer 'buf' of length 'len' bytes
  490.  */
  491. FullName(fname, buf, len)
  492.     char        *fname, *buf;
  493.     int            len;
  494. {
  495.     BPTR        l;
  496.     int            retval = 0;
  497.  
  498.     if (fname == NULL)    /* always fail */
  499.         return 0;
  500.  
  501.     if ((l = Lock((UBYTE *)fname, (long)ACCESS_READ)))/* lock the file */
  502.     {
  503.         retval = lock2name(l, buf, (long)len);
  504.         UnLock(l);
  505.     }
  506.     if (retval == 0 || *buf == 0 || *buf == ':')
  507.         strcpy(buf, fname);            /* something failed; use the filename */
  508.     return retval;
  509. }
  510.  
  511. /*
  512.  * Get the full filename from a lock. Use 2.0 function if possible, because
  513.  * the arp function has more restrictions on the path length.
  514.  */
  515.     static int
  516. lock2name(lock, buf, len)
  517.     BPTR    lock;
  518.     char    *buf;
  519.     long    len;
  520. {
  521.     if (dos2)
  522.         return (int)NameFromLock(lock, (UBYTE *)buf, len);
  523.     else
  524.         return (int)PathName(lock, buf, (long)(len/32));        /* call arp function */
  525. }
  526.  
  527. /*
  528.  * get file permissions for 'name'
  529.  */
  530.     long
  531. getperm(name)
  532.     char        *name;
  533. {
  534.     struct FileInfoBlock    *fib;
  535.     long                     retval = -1;
  536.  
  537.     fib = get_fib(name);
  538.     if (fib != NULL)
  539.     {
  540.         retval = fib->fib_Protection;
  541.         free(fib);
  542.     }
  543.     return retval;
  544. }
  545.  
  546. #ifdef DEBUG
  547. /*
  548.  * check for write lock
  549.  */
  550.     long
  551. writelock(name)
  552.     char        *name;
  553. {
  554.     BPTR            lock;
  555.  
  556.     lock = Lock(name, (long)ACCESS_READ);
  557.     if (lock)
  558.     {
  559.         UnLock(lock);
  560.         lock = Lock(name, (long)ACCESS_WRITE);
  561.         if (lock)
  562.         {
  563.             UnLock(lock);
  564.             return TRUE;        /* can write-lock */
  565.         }
  566.         return FALSE;            /* can read-lock but not write-lock */
  567.     }
  568.     return TRUE;                /* file does not exist */
  569. }
  570. #endif
  571.  
  572. /*
  573.  * set file permission for 'name' to 'perm'
  574.  */
  575. setperm(name, perm)
  576.     char        *name;
  577.     long        perm;
  578. {
  579.     perm &= ~FIBF_ARCHIVE;                /* reset archived bit */
  580.     return (int)SetProtection((UBYTE *)name, (long)perm);
  581. }
  582.  
  583. /*
  584.  * check if "name" is a directory
  585.  */
  586. isdir(name)
  587.     char        *name;
  588. {
  589.     struct FileInfoBlock    *fib;
  590.     int                     retval = -1;
  591.  
  592.     fib = get_fib(name);
  593.     if (fib != NULL)
  594.     {
  595.         retval = (fib->fib_DirEntryType >= 0);
  596.         free(fib);
  597.     }
  598.     return retval;
  599. }
  600.  
  601. /*
  602.  * Careful: mch_windexit() may be called before mch_windinit()!
  603.  */
  604.     void
  605. mch_windexit(r)
  606.     int             r;
  607. {
  608.     if (raw_out)
  609.     {
  610.         if (term_console)
  611.         {
  612.             outstr(win_resize_off);        /* window resize events de-activated */
  613.             if (size_set)
  614.                 outstr("\233t\233u");        /* reset window size (CSI t CSI u) */
  615.         }
  616.         flushbuf();
  617.     }
  618.  
  619.     if (wb_window != NULL)            /* disable window title */
  620.         SetWindowTitles(wb_window, (UBYTE *)oldwindowtitle, (UBYTE *)-1L);
  621.     if (raw_in)
  622.         settmode(0);
  623.     stopscript();                    /* remove autoscript file */
  624.     if (ArpBase)
  625.         CloseLibrary((struct Library *) ArpBase);
  626.     if (close_win)
  627.         Close(raw_in);
  628.     if (r)
  629.         printf("exiting with %d\n", r);    /* somehow this makes :cq work!? */
  630.     exit(r);
  631. }
  632.  
  633. /*
  634.  * This is a routine for setting a given stream to raw or cooked mode on the
  635.  * Amiga . This is useful when you are using Lattice C to produce programs
  636.  * that want to read single characters with the "getch()" or "fgetc" call.
  637.  *
  638.  * Written : 18-Jun-87 By Chuck McManis.
  639.  */
  640.  
  641. #define MP(xx)    ((struct MsgPort *)((struct FileHandle *) (BADDR(xx)))->fh_Type)
  642.  
  643. /*
  644.  * Function mch_settmode() - Convert the specified file pointer to 'raw' or 'cooked'
  645.  * mode. This only works on TTY's.
  646.  *
  647.  * Raw: keeps DOS from translating keys for you, also (BIG WIN) it means
  648.  *        getch() will return immediately rather than wait for a return. You
  649.  *        lose editing features though.
  650.  *
  651.  * Cooked: This function returns the designate file pointer to it's normal,
  652.  *        wait for a <CR> mode. This is exactly like raw() except that
  653.  *        it sends a 0 to the console to make it back into a CON: from a RAW:
  654.  */
  655.     void
  656. mch_settmode(raw)
  657.     int            raw;
  658. {
  659.     if (dos_packet(MP(raw_in), (long)ACTION_SCREEN_MODE, raw ? -1L : 0L) == 0)
  660.         fprintf(stderr, "cannot change console mode ?!\n");
  661. }
  662.  
  663. /*
  664.  * Code for this routine came from the following :
  665.  *
  666.  * ConPackets.c -  C. Scheppner, A. Finkel, P. Lindsay    CBM
  667.  *     DOS packet example
  668.  *     Requires 1.2
  669.  *
  670.  * Found on Fish Disk 56.
  671.  *
  672.  * Heavely modified by mool.
  673.  */
  674.  
  675. #include <devices/conunit.h>
  676.  
  677. /*
  678.  * try to get the real window size
  679.  * return non-zero for failure
  680.  */
  681.     int
  682. mch_get_winsize()
  683. {
  684.     struct ConUnit    *conUnit;
  685.      char            id_a[sizeof(struct InfoData) + 3];
  686.     struct InfoData *id;
  687.  
  688.     if (!term_console)    /* not an amiga window */
  689.         return 1;
  690.  
  691.     /* insure longword alignment */
  692.      id = (struct InfoData *)(((long)id_a + 3L) & ~3L);
  693.  
  694.     /*
  695.      * Should make console aware of real window size, not the one we set.
  696.      * Unfortunately, under DOS 2.0x this redraws the window and it
  697.      * is rarely needed, so we skip it now, unless we changed the size.
  698.      */
  699.     if (size_set)
  700.         outstr("\233t\233u");    /* CSI t CSI u */
  701.     flushbuf();
  702.  
  703.     if (dos_packet(MP(raw_out), (long)ACTION_DISK_INFO, ((ULONG) id) >> 2) == 0 ||
  704.                 (wb_window = (struct Window *)id->id_VolumeNode) == NULL)
  705.     {
  706.         /* it's not an amiga window, maybe aux device */
  707.         /* terminal type should be set */
  708.         term_console = FALSE;
  709.         return 1;
  710.     }
  711.     if (oldwindowtitle == NULL)
  712.         oldwindowtitle = (char *)wb_window->Title;
  713.     if (id->id_InUse == (BPTR)NULL)
  714.     {
  715.         fprintf(stderr, "mch_get_winsize: not a console??\n");
  716.         return (2);
  717.     }
  718.     conUnit = (struct ConUnit *) ((struct IOStdReq *) id->id_InUse)->io_Unit;
  719.  
  720.     /* get window size */
  721.     Rows = conUnit->cu_YMax + 1;
  722.     Columns = conUnit->cu_XMax + 1;
  723.     if (Rows < 0 || Rows > 200)     /* cannot be an amiga window */
  724.     {
  725.         Columns = 80;
  726.         Rows = 24;
  727.         term_console = FALSE;
  728.         return 1;
  729.     }
  730.  
  731.     check_winsize();
  732.     script_winsize();
  733.  
  734.     return 0;
  735. }
  736.  
  737. /*
  738.  * try to set the real window size
  739.  */
  740.     void
  741. mch_set_winsize()
  742. {
  743.     if (term_console)
  744.     {
  745.         size_set = TRUE;
  746.         outchar(CSI);
  747.         outnum((int)Rows);
  748.         outchar('t');
  749.         outchar(CSI);
  750.         outnum((int)Columns);
  751.         outchar('u');
  752.         flushbuf();
  753.     }
  754. }
  755.  
  756. #ifdef SETKEYMAP
  757. /*
  758.  * load and activate a new keymap for our CLI - DOES NOT WORK -
  759.  * The problem is that after the setting of the keymap the input blocks
  760.  * But the new keymap works allright in another window.
  761.  * Tried but no improvement:
  762.  * - remembering the length, data and command fields in request->io_xxx
  763.  * - settmode(0) first, settmode(1) afterwards
  764.  * - putting the keymap directly in conunit structure
  765.  */
  766.  
  767. #include <devices/keymap.h>
  768.  
  769.     void
  770. set_keymap(name)
  771.     char *name;
  772. {
  773.      char                    id_a[sizeof(struct InfoData) + 3];
  774.     struct InfoData            *id;
  775.     static struct KeyMap    *old;
  776.     static BPTR                segment = (BPTR)NULL;
  777.     struct IOStdReq            *request;
  778.     int                        c;
  779.  
  780.     if (!term_console)
  781.         return;
  782.  
  783.     /* insure longword alignment */
  784.      id = (struct InfoData *)(((long)id_a + 3L) & ~3L);
  785.  
  786.     if (dos_packet(MP(raw_out), (long)ACTION_DISK_INFO, ((ULONG) id) >> 2) == 0)
  787.     {
  788.         emsg("dos_packet failed");
  789.         return;
  790.     }
  791.     if (id->id_InUse == (BPTR)NULL)
  792.     {
  793.         emsg("not a console??");
  794.         return;
  795.     }
  796.     request = (struct IOStdReq *) id->id_InUse;
  797.  
  798.     if (segment != (BPTR)NULL)    /* restore old keymap */
  799.     {
  800.         request->io_Command = CD_SETKEYMAP;
  801.         request->io_Length = sizeof(struct KeyMap);
  802.         request->io_Data = (APTR)old;
  803.         DoIO((struct IORequest *)request);
  804.         if (request->io_Error)
  805.             emsg("Cannot reset keymap");
  806.         else                /* no error, free the allocated memory */
  807.         {
  808.             UnLoadSeg(segment);
  809.             FreeMem(old, sizeof(struct KeyMap));
  810.             segment = (BPTR)NULL;
  811.         }
  812.     }
  813.     if (name != NULL)
  814.     {
  815.         segment = LoadSeg(name);
  816.         if (segment == (BPTR)NULL)
  817.         {
  818.             emsg("Cannot open keymap file");
  819.             return;
  820.         }
  821.         old = (struct KeyMap *)AllocMem(sizeof(struct KeyMap), MEMF_PUBLIC);
  822.         if (old == NULL)
  823.         {
  824.             emsg(e_outofmem);
  825.             UnLoadSeg(segment);
  826.             segment = (BPTR)NULL;
  827.         }
  828.         else
  829.         {
  830.             request->io_Command = CD_ASKKEYMAP;
  831.             request->io_Length = sizeof(struct KeyMap);
  832.             request->io_Data = (APTR)old;
  833.             DoIO((struct IORequest *)request);
  834.             if (request->io_Error)
  835.             {
  836.                 emsg("Cannot get old keymap");
  837.                 UnLoadSeg(segment);
  838.                 segment = (BPTR)NULL;
  839.                 FreeMem(old, sizeof(struct KeyMap));
  840.             }
  841.             else
  842.             {
  843.                 request->io_Command = CD_SETKEYMAP;
  844.                 request->io_Length = sizeof(struct KeyMap);
  845.                 request->io_Data = (APTR)((segment << 2) + 18);
  846.                 DoIO((struct IORequest *)request);
  847.                 if (request->io_Error)
  848.                     emsg("Cannot set keymap");
  849.  
  850.                 /* test for blocking */
  851.                 request->io_Command = CMD_READ;
  852.                 request->io_Length = 1;
  853.                 request->io_Data = (APTR)&c;
  854.                 DoIO((struct IORequest *)request);    /* BLOCK HERE! */
  855.                 if (request->io_Error)
  856.                     emsg("Cannot set keymap");
  857.             }
  858.         }
  859.     }
  860. }
  861. #endif
  862.  
  863. #ifndef AZTEC_C
  864. /*
  865.  * Sendpacket.c
  866.  *
  867.  * An invaluable addition to your Amiga.lib file. This code sends a packet to
  868.  * the given message port. This makes working around DOS lots easier.
  869.  *
  870.  * Note, I didn't write this, those wonderful folks at CBM did. I do suggest
  871.  * however that you may wish to add it to Amiga.Lib, to do so, compile it and
  872.  * say 'oml lib:amiga.lib -r sendpacket.o'
  873.  */
  874.  
  875. /* #include <proto/exec.h> */
  876. /* #include <proto/dos.h> */
  877. #include <exec/memory.h>
  878.  
  879. /*
  880.  * Function - dos_packet written by Phil Lindsay, Carolyn Scheppner, and Andy
  881.  * Finkel. This function will send a packet of the given type to the Message
  882.  * Port supplied.
  883.  */
  884.  
  885.     static long
  886. dos_packet(pid, action, arg)
  887.     struct MsgPort *pid;        /* process indentifier ... (handlers message
  888.                                  * port ) */
  889.     long            action,     /* packet type ... (what you want handler to
  890.                                  * do )   */
  891.                     arg;        /* single argument */
  892. {
  893.     struct MsgPort *replyport;
  894.     struct StandardPacket *packet;
  895.  
  896.     long            res1;
  897.  
  898.     replyport = (struct MsgPort *) CreatePort(NULL, 0);
  899.     if (!replyport)
  900.         return (0);
  901.  
  902.     /* Allocate space for a packet, make it public and clear it */
  903.     packet = (struct StandardPacket *)
  904.         AllocMem((long) sizeof(struct StandardPacket), MEMF_PUBLIC | MEMF_CLEAR);
  905.     if (!packet) {
  906.         DeletePort(replyport);
  907.         return (0);
  908.     }
  909.     packet->sp_Msg.mn_Node.ln_Name = (char *) &(packet->sp_Pkt);
  910.     packet->sp_Pkt.dp_Link = &(packet->sp_Msg);
  911.     packet->sp_Pkt.dp_Port = replyport;
  912.     packet->sp_Pkt.dp_Type = action;
  913.     packet->sp_Pkt.dp_Arg1 = arg;
  914.  
  915.     PutMsg(pid, (struct Message *)packet);        /* send packet */
  916.  
  917.     WaitPort(replyport);
  918.     GetMsg(replyport);
  919.  
  920.     res1 = packet->sp_Pkt.dp_Res1;
  921.  
  922.     FreeMem(packet, (long) sizeof(struct StandardPacket));
  923.     DeletePort(replyport);
  924.  
  925.     return (res1);
  926. }
  927. #endif
  928.  
  929. /*
  930.  * call shell, return non-zero for failure
  931.  */
  932.     int
  933. call_shell(cmd, filter)
  934.         char    *cmd;
  935.         int        filter;        /* if != 0: called by dofilter() */
  936. {
  937.     BPTR mydir;
  938.     int x;
  939. #ifndef LATTICE
  940.     int    use_execute;
  941. #endif
  942.     int    retval = 0;
  943.  
  944.     if (close_win)
  945.     {
  946.         /* if Vim opened a window: Executing a shell may cause crashes */
  947.         emsg("Cannot execute shell with -e option");
  948.         return 1;
  949.     }
  950.  
  951.     if (term_console)
  952.         outstr(win_resize_off);     /* window resize events de-activated */
  953.     flushbuf();
  954.  
  955.     settmode(0);                 /* set to cooked mode */
  956.     mydir = Lock((UBYTE *)"", (long)ACCESS_READ);    /* remember current directory */
  957.  
  958. #ifdef LATTICE        /* not tested yet */
  959.     if (cmd == NULL)
  960.         x = Execute(p_sh, raw_in, raw_out);
  961.     else
  962.         x = Execute(cmd, 0L, raw_out);
  963.     if (!x)
  964.     {
  965.         if (cmd == NULL)
  966.             smsg("Cannot execute shell %s", p_sh);
  967.         else
  968.             smsg("Cannot execute %s", cmd);
  969.         outchar('\n');
  970.         retval = 1;
  971.     }
  972.     else
  973.     {
  974.         if (x = IoErr())
  975.         {
  976.             smsg("%d returned", x);
  977.             outchar('\n');
  978.             retval = 1;
  979.         }
  980.     }
  981. #else
  982.     if (p_st >= 4 || (p_st >= 2 && !filter))
  983.         use_execute = 1;
  984.     else
  985.         use_execute = 0;
  986.     if (cmd == NULL)
  987.     {
  988.         use_execute = 0;
  989.         x = fexecl(p_sh, p_sh, NULL);
  990.     }
  991.     else if (use_execute)
  992.         x = !Execute((UBYTE *)cmd, 0L, raw_out);
  993.     else if (p_st & 1)
  994.         x = fexecl(p_sh, p_sh, cmd, NULL);
  995.     else
  996.         x = fexecl(p_sh, p_sh, "-c", cmd, NULL);
  997.     if (x)
  998.     {
  999.         if (use_execute)
  1000.             smsg("Cannot execute %s", cmd);
  1001.         else
  1002.             smsg("Cannot execute shell %s", p_sh);
  1003.         outchar('\n');
  1004.         retval = 1;
  1005.     }
  1006.     else
  1007.     {
  1008.         if (use_execute)
  1009.             x = IoErr();
  1010.         else
  1011.             x = wait();
  1012.         if (x)
  1013.         {
  1014.             smsg("%d returned", x);
  1015.             outchar('\n');
  1016.             retval = 1;
  1017.         }
  1018.     }
  1019. #endif
  1020.  
  1021.     if (mydir = CurrentDir(mydir))        /* make sure we stay in the same directory */
  1022.         UnLock(mydir);
  1023.     settmode(1);                         /* set to raw mode */
  1024.     resettitle();
  1025.     if (term_console)
  1026.         outstr(win_resize_on);             /* window resize events activated */
  1027.     return retval;
  1028. }
  1029.  
  1030. /*
  1031.  * check for an "interrupt signal"
  1032.  * We only react to a CTRL-C, but also clear the other break signals to avoid trouble
  1033.  * with lattice-c programs.
  1034.  */
  1035.     void
  1036. breakcheck()
  1037. {
  1038.    if (SetSignal(0L, (long)(SIGBREAKF_CTRL_C|SIGBREAKF_CTRL_D|SIGBREAKF_CTRL_E|SIGBREAKF_CTRL_F)) & SIGBREAKF_CTRL_C)
  1039.     {
  1040.         got_int = TRUE;
  1041.         flush_buffers();    /* remove all typeahead and macro stuff */
  1042.     }
  1043. }
  1044.  
  1045. /* this routine causes manx to use this Chk_Abort() rather than it's own */
  1046. /* otherwise it resets our ^C when doing any I/O (even when Enable_Abort */
  1047. /* is zero).  Since we want to check for our own ^C's                    */
  1048.  
  1049. #ifdef _DCC
  1050. #define Chk_Abort chkabort
  1051. #endif
  1052.  
  1053.     long
  1054. Chk_Abort()
  1055. {
  1056.     return(0L);
  1057. }
  1058.  
  1059. #ifdef WILD_CARDS
  1060. /*
  1061.  * ExpandWildCard() - this code does wild-card pattern matching using the arp
  1062.  *                      routines. This is based on WildDemo2.c (found in arp1.1
  1063.  *                      distribution). That code's copyright follows :
  1064.  *-------------------------------------------------------------------------
  1065.  * WildDemo2.c - Search filesystem for patterns, and separate into directories
  1066.  *         and files, sorting each separately using DA lists.
  1067.  *
  1068.  * -+=SDB=+-
  1069.  *
  1070.  * Copyright (c) 1987, Scott Ballantyne
  1071.  * Use and abuse as you please.
  1072.  *
  1073.  * num_pat is number of input patterns
  1074.  * pat is array of pointers to input patterns
  1075.  * num_file is pointer to number of matched file names
  1076.  * file is pointer to array of pointers to matched file names
  1077.  * if file_only is TRUE we match only files, no dirs
  1078.  * if list_notfound is TRUE we include not-found entries (probably locked)
  1079.  * return 0 for success, 1 for error (you may loose some memory)
  1080.  *-------------------------------------------------------------------------
  1081.  */
  1082.  
  1083. /* #include <arpfunctions.h> */
  1084. extern void *malloc __ARGS((size_t)), *calloc __ARGS((size_t, size_t));
  1085.  
  1086. #define ANCHOR_BUF_SIZE (512)
  1087. #define ANCHOR_SIZE (sizeof(struct AnchorPath) + ANCHOR_BUF_SIZE)
  1088.  
  1089. ExpandWildCards(num_pat, pat, num_file, file, files_only, list_notfound)
  1090.     int             num_pat;
  1091.     char          **pat;
  1092.     int            *num_file;
  1093.     char         ***file;
  1094.     int            files_only;
  1095.     int            list_notfound;
  1096. {
  1097.     int         i;
  1098.     int         retval = 0;
  1099.  
  1100.     struct DirectoryEntry *FileList = NULL;
  1101.     struct DirectoryEntry *de;
  1102.     struct AnchorPath *Anchor;
  1103.     LONG            Result;
  1104.  
  1105.     *num_file = 0;
  1106.     *file = (char **)"";
  1107.  
  1108.     /* Get our AnchorBase */
  1109.     Anchor = (struct AnchorPath *) calloc((size_t)1, (size_t)ANCHOR_SIZE);
  1110.     if (!Anchor)
  1111.     {
  1112. OUT_OF_MEMORY:
  1113.         retval = 1;
  1114.         *file = (char **)"Out of memory";
  1115.         goto Return;
  1116.     }
  1117. #ifdef LATTICE
  1118.     Anchor->ap_Length = ANCHOR_BUF_SIZE;
  1119. #else
  1120.     Anchor->ap_StrLen = ANCHOR_BUF_SIZE;
  1121. #endif
  1122.  
  1123.     if (num_pat > 0)
  1124.     {
  1125.         for (i = 0; i < num_pat; i++)
  1126.         {
  1127.             Result = FindFirst(pat[i], Anchor);
  1128.             while (Result == 0)
  1129.             {
  1130.                 if (!files_only || Anchor->ap_Info.fib_DirEntryType < 0)
  1131.                 {
  1132.                     (*num_file)++;
  1133.                     if (!AddDANode(Anchor->ap_Buf, &FileList, 0L, (long)i))
  1134.                     {
  1135.                         FreeAnchorChain(Anchor);
  1136.                         FreeDAList(FileList);
  1137.                         goto OUT_OF_MEMORY;
  1138.                     }
  1139.                 }
  1140.                 Result = FindNext(Anchor);
  1141.             }
  1142.             if (Result == ERROR_BUFFER_OVERFLOW)
  1143.             {
  1144.                 FreeAnchorChain(Anchor);
  1145.                 FreeDAList(FileList);
  1146.                 retval = 1;
  1147.                 *file = (char **)"ANCHOR_BUF_SIZE too small.";
  1148.                 goto Return;
  1149.             }
  1150.             if (Result != ERROR_NO_MORE_ENTRIES)
  1151.             {
  1152.                 if (list_notfound)    /* put object with error in list */
  1153.                 {
  1154.                     (*num_file)++;
  1155.                     if (!AddDANode(pat[i], &FileList, 0L, (long)i))
  1156.                     {
  1157.                         FreeAnchorChain(Anchor);
  1158.                         FreeDAList(FileList);
  1159.                         goto OUT_OF_MEMORY;
  1160.                     }
  1161.                 }
  1162.                 else if (Result != ERROR_OBJECT_NOT_FOUND)
  1163.                 {
  1164.                     FreeAnchorChain(Anchor);
  1165.                     FreeDAList(FileList);
  1166.                     retval = 1;
  1167.                     *file = (char **)"I/O ERROR";
  1168.                     goto Return;
  1169.                 }
  1170.             }
  1171.         }
  1172.         FreeAnchorChain(Anchor);
  1173.  
  1174.         de = FileList;
  1175.         if (de)
  1176.         {
  1177.             *file = (char **) malloc(sizeof(char *) * (*num_file));
  1178.             if (*file == NULL)
  1179.                 goto OUT_OF_MEMORY;
  1180.             for (i = 0; de; de = de->de_Next, i++)
  1181.             {
  1182.                 (*file)[i] = (char *) malloc(strlen(de->de_Name) + 1);
  1183.                 if ((*file)[i] == NULL)
  1184.                     goto OUT_OF_MEMORY;
  1185.                 strcpy((*file)[i], de->de_Name);
  1186.             }
  1187.         }
  1188.         FreeDAList(FileList);
  1189.     }
  1190. Return:
  1191.     return retval;
  1192. }
  1193.  
  1194. void
  1195. FreeWild(num, file)
  1196.         int num;
  1197.         char **file;
  1198. {
  1199.         if (file == NULL || num == 0)
  1200.                 return;
  1201.         while (num--)
  1202.                 free(file[num]);
  1203.         free(file);
  1204. }
  1205. #endif
  1206.